package com.gzhryc.shared_device.bxscn.code.services;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.pay.adaptation.weixin.WXPayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.enums.EWXPayNormalRefundState;
import com.gzhryc.pay.adaptation.weixin.msg.normal.WXPayNormalRefundResponse;
import com.gzhryc.shared_device.base.IMemberCouponService;
import com.gzhryc.shared_device.base.IMemberWalletService;
import com.gzhryc.shared_device.base.IPayServiceFactory;
import com.gzhryc.shared_device.base.enums.*;
import com.gzhryc.shared_device.base.models.IMemberCoupon;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.base.models.OrderLogContent;
import com.gzhryc.shared_device.bxscn.code.IBXSCNShopBusinessEventListener;
import com.gzhryc.shared_device.bxscn.code.dao.BXSCNShopOrderDao;
import com.gzhryc.shared_device.bxscn.code.dao.db.*;
import com.gzhryc.shared_device.bxscn.code.dao.enums.BXSCNShopOrderEnum;
import com.gzhryc.shared_device.bxscn.code.dao.enums.PortableEnergyBatteryEnum;
import com.gzhryc.shared_device.bxscn.code.services.dto.BXSCNShopOrderSearch;
import com.gzhryc.shared_device.bxscn.core.BXSCNConstants;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXRefundOrder;
import com.gzhryc.shared_device.common.payment.services.WXPayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXRefundOrderService;
import org.apache.commons.lang3.time.DateUtils;

import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BXSCNShopOrderService {

    static Logger log = Logger.getLogger(BXSCNShopOrderService.class);

    public static BXSCNShopOrderService self(Date date) {
        return MultiDBTools.getService(BXSCNShopOrderService.class,date);
    }

    public static BXSCNShopOrderService self(String jdbcKey, Date date) {
        return MultiDBTools.getService(jdbcKey, BXSCNShopOrderService.class, date);
    }

    BXSCNShopOrderDao dao;

    public BXSCNShopOrderService(String jdbcKey, Date date) {
        dao = new BXSCNShopOrderDao(jdbcKey,date);
    }

    public List<BXSCNShopOrder> findBySearch(BXSCNShopOrderSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().lt("startDate",search.getLeaseTimeoutDate());
        conditions.and().lt("endDate",search.getRevertTimeoutDate());
        conditions.and().ge("payState",search.getMinPayState());
        conditions.and().in("leasePlaceId",search.getLeasePlaceIds());
        conditions.desc("createDate");
        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public List<BXSCNShopOrder> findByTradeNoList(List<String> tradeNoList) {
        if (tradeNoList != null && tradeNoList.size() > 0) {
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().in("tradeNo", tradeNoList);
            conditions.desc("createDate");
            try {
                return dao.findByCondition(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public Long countBySearch(BXSCNShopOrderSearch search){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().lt("startDate",search.getLeaseTimeoutDate());
        conditions.and().lt("endDate",search.getRevertTimeoutDate());
        conditions.and().ge("payState",search.getMinPayState());
        conditions.and().in("leasePlaceId",search.getLeasePlaceIds());
        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return 0L;
    }

    public BXSCNShopOrder getByTradeNo(String tradeNo){
        try {
            return dao.getById(tradeNo);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public boolean paySuccess(BXSCNShopOrder deviceOrder, OrderLogContent logContent ,IMemberWalletService memberWalletService,OperateInfo operateInfo) throws LogicException {
        boolean flag = false;

        deviceOrder.setPayState(BXSCNShopOrderEnum.PayState.DepositSuccess.index());
        deviceOrder.setPayDate(new Date());

        JdbcSession.begin();
        try {
            flag = dao.insert(deviceOrder) > 0;
            if(flag){
                Long payMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(deviceOrder.getPayMoney()));
                if(payMoney > 0) {
                    flag = memberWalletService.addFreezeMoney(deviceOrder.getMemberId(), payMoney, operateInfo);
                }
                if(flag && deviceOrder.getWalletMoney() > 0){
                    flag = memberWalletService.freezeMoney(deviceOrder.getMemberId(), deviceOrder.getWalletMoney(), operateInfo);
                }
                if(flag) {
                    JdbcSession.commit();
                }
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        } finally {
            JdbcSession.end();
        }

        if (flag) {
            //增加日志
            if (StringTools.isBlank(operateInfo.getOperateNote())) {
                operateInfo.setOperateNote("订单支付成功");
            }
            BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, logContent, operateInfo, ELogState.Success.index(), null);
            return true;
        } else {
            log.error("新增便携式储能门店订单失败，订单信息：{{0:json}}", deviceOrder);
        }
        return false;
    }

    /**
     * 租借超时，只修改状态
     * @param deviceOrder
     * @param operateInfo
     * @return
     */
    public boolean leaseTimeout(BXSCNShopOrder deviceOrder,OperateInfo operateInfo){
        if (deviceOrder != null && StringTools.isNotBlank(deviceOrder.getTradeNo())) {
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo", deviceOrder.getTradeNo());
            conditions.and().is("state", BXSCNShopOrderEnum.State.WaitLease.index());
            conditions.and().is("payState",BXSCNShopOrderEnum.PayState.DepositSuccess.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setState(BXSCNShopOrderEnum.State.LeaseTimeout.index());

            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                    //记录日志
                    operateInfo.setOperateNote("修改订单状态为：租借超时");
                    BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, ELogState.Success.index(), null);
                    return true;
                }
            }catch (SQLException e){
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    /**
     * 租借超时，收取1天的费用，其他的进行退款
     * @param deviceOrder
     * @param payServiceFactory
     * @param operateInfo
     * @return
     */
    public boolean leaseTimeout(BXSCNShopOrder deviceOrder,IPayServiceFactory payServiceFactory,OperateInfo operateInfo) {
        if (deviceOrder != null && StringTools.isNotBlank(deviceOrder.getTradeNo())) {
            IMemberWalletService memberWalletService = payServiceFactory.getMemberWalletService();

            if (EPayType.EWallet.index().equals(deviceOrder.getPayType())) {
                //TODO 暂不支持
            } else {
                Conditions conditions = new Conditions(BXSCNShopOrder.class);
                conditions.and().is("tradeNo", deviceOrder.getTradeNo());
                conditions.and().is("payState",BXSCNShopOrderEnum.PayState.DepositSuccess.index());
                //等待租借或租借超时
                conditions.and().is("state", BXSCNShopOrderEnum.State.WaitLease.index()).or().is("state", BXSCNShopOrderEnum.State.LeaseTimeout.index());

                BXSCNShopOrder updateEntity = new BXSCNShopOrder();
                updateEntity.setState(BXSCNShopOrderEnum.State.LeaseTimeout.index());
                updateEntity.setUseDay(1);
                updateEntity.setFinishDate(new Date());

                //计算一天的费用
                Long payMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(deviceOrder.getDayMoney()));
                Long refundMoneyLi = deviceOrder.getIncomeMoney() - payMoney;

                updateEntity.setMoney(payMoney);
                updateEntity.setPayMoney(deviceOrder.getDayMoney());

                boolean isSuccess = false;
                Integer logState = ELogState.Success.index();
                String errorMsg = null;

                JdbcSession.begin();
                try {
                    if (dao.updateNotNull(updateEntity, conditions) > 0) {
                        operateInfo.setOperateNote(deviceOrder.getTradeNo() + "订单超时租借收取一天的租费");
                        //扣除租借费
                        if (memberWalletService.reduceFreezeMoney(deviceOrder.getMemberId(), deviceOrder.getIncomeMoney(), operateInfo)) {
                            JdbcSession.commit();
                            isSuccess = true;
                        } else {
                            log.error("{{0}}订单修改{{1}}用户钱包失败", deviceOrder.getTradeNo(), deviceOrder.getMemberId());
                        }
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                } catch (LogicException e) {
                    log.error(e.getMessage(),e);
                } finally {
                    JdbcSession.end();
                }

                if (isSuccess && refundMoneyLi > 0) {
                    //触发押金退款
                    if (EPayType.WXPay.index().equals(deviceOrder.getPayType())) {
                        WXPayOrder payOrder = WXPayOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getPayTradeNo());
                        if (payOrder != null) {
                            WXPayNormalPayService payService = payServiceFactory.getWXPayNormalPayService(payOrder.getAppId(), BXSCNConstants.BusinessTypeShop);
                            if (payService != null) {
                                if (noOperateTo(deviceOrder.getTradeNo(), EOrderOperateState.Finishing.index())) {
                                    //触发退款
                                    try {
                                        Integer refundMoney = NumberTools.changeMoney(NumberTools.changeMoneyLi(refundMoneyLi));
                                        WXRefundOrder refundOrder = WXRefundOrderService.self(deviceOrder.getCreateDate()).createRefundOrder(payOrder, refundMoney, operateInfo.getOperateNote());
                                        if (refundOrder != null) {
                                            WXPayNormalRefundResponse externalResult = payService.applyRefundOrder(refundOrder);
                                            if (externalResult != null) {
                                                if(StringTools.isNotBlank(externalResult.getCode()) && StringTools.isNotBlank(externalResult.getMessage())){
                                                    logState = ELogState.Fail.index();
                                                    errorMsg = externalResult.getMessage();
                                                    log.error("{{0}}订单微信退款失败，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                                                }else if(EWXPayNormalRefundState.ABNORMAL.name().equals(externalResult.getStatus())) {
                                                    logState = ELogState.Fail.index();
                                                    errorMsg = "退款订单异常";
                                                    log.error("{{0}}订单微信退款失败，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                                                }else if(EWXPayNormalRefundState.CLOSED.name().equals(externalResult.getStatus())) {
                                                    logState = ELogState.Fail.index();
                                                    errorMsg = "退款订单已关闭";
                                                    log.error("{{0}}订单微信退款失败，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                                                }
                                            } else {
                                                logState = ELogState.Fail.index();
                                                errorMsg = "微信退款失败，无响应";
                                                log.error("{{0}}订单微信退款失败，无返回信息", payOrder.getTradeNo());
                                            }
                                        } else {
                                            logState = ELogState.Fail.index();
                                            errorMsg = "创建微信退款订单失败";
                                        }
                                    } catch (Exception e) {
                                        log.error(e.getMessage(), e);
                                        logState = ELogState.Fail.index();
                                        errorMsg = e.getMessage();
                                    }

                                    if (ELogState.Fail.index().equals(logState)) {
                                        //失败回滚数据库
                                        faceOperateState(deviceOrder.getTradeNo(), EOrderOperateState.NoOperation.index());
                                    }
                                } else {
                                    logState = ELogState.Fail.index();
                                    errorMsg = "退款时锁定订单失败";
                                }
                            } else {
                                logState = ELogState.Fail.index();
                                errorMsg = "退款时未找到应用支付服务";
                                log.error("{{0}}订单归还成功后未找到应用支付服务", deviceOrder.getTradeNo());
                            }
                        } else {
                            logState = ELogState.Fail.index();
                            errorMsg = "退款时未找到支付订单";
                            log.error("{{0}}订单归还成功后未找到{{1}}支付订单", deviceOrder.getTradeNo(), deviceOrder.getPayTradeNo());
                        }
                    }
                }

                //记录日志
                operateInfo.setOperateNote("租借超时，收取一天的租金，其余退款");
                BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
                return true;
            }
        }
        return false;
    }

    public boolean leaseFinish(BXSCNShopOrder deviceOrder, OperateInfo operateInfo, IBXSCNShopBusinessEventListener businessEventListener) throws LogicException {
        if (deviceOrder != null && StringTools.isNotBlank(deviceOrder.getTradeNo())) {
            Integer logState = ELogState.Fail.index();
            String errorMsg = "系统操作失败";
            operateInfo.setOperateNote("租借电池成功");

            if (!BXSCNShopOrderEnum.LeaseType.Appointment.index().equals(deviceOrder.getLeaseType())) {
                throw new LogicException("请选择同城快递操作");
            }
            if (!BXSCNShopOrderEnum.State.WaitLease.index().equals(deviceOrder.getState())) {
                errorMsg = "订单状态异常，当前状态：" + deviceOrder.getStateName();
            }

            if (!BXSCNShopOrderEnum.PayState.DepositSuccess.index().equals(deviceOrder.getPayState())) {
                errorMsg = "订单支付状态异常，当前支付状态：" + deviceOrder.getPayStateName();
            }

            if (!EOrderOperateState.NoOperation.index().equals(deviceOrder.getOperateState())) {
                throw new LogicException("订单繁忙，请稍后再试");
            }

            if (StringTools.isNotBlank(deviceOrder.getPortableBatterySn())) {
                PortableEnergyBattery portableEnergyBattery = PortableEnergyBatteryService.self().getByDeviceSn(deviceOrder.getPortableBatterySn());
                if (portableEnergyBattery == null) {
                    throw new LogicException("未找到电池信息");
                } else if (PortableEnergyBatteryEnum.State.Lease.index().equals(portableEnergyBattery.getState())) {
                    throw new LogicException("电池租借中");
                } else if (PortableEnergyBatteryEnum.State.Stock.index().equals(portableEnergyBattery.getState())) {
                    throw new LogicException("电池未部署网点");
                } else if (portableEnergyBattery.getPlaceId() == null || !portableEnergyBattery.getPlaceId().equals(deviceOrder.getLeasePlaceId())) {
                    throw new LogicException("电池部署网点与租借网点不一致");
                }else if(!deviceOrder.getBatteryType().equals(portableEnergyBattery.getType())){
                    throw new LogicException("电池型号与租借订单不一致");
                }
            } else {
                throw new LogicException("请填写租借的电池序列号");
            }

            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo", deviceOrder.getTradeNo());
            conditions.and().is("state", BXSCNShopOrderEnum.State.WaitLease.index());
            conditions.and().is("operateState", EOrderOperateState.NoOperation.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setLeaseOperatorId(operateInfo.getOperatorId());
            updateEntity.setLeaseOperator(operateInfo.getOperator());
            updateEntity.setState(BXSCNShopOrderEnum.State.Lease.index());
            updateEntity.setPortableBatterySn(deviceOrder.getPortableBatterySn());
            updateEntity.setLeaseType(deviceOrder.getLeaseType());
            updateEntity.setStartDate(deviceOrder.getStartDate());
            updateEntity.setEndDate(deviceOrder.getEndDate());

            JdbcSession.begin();
            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                    //修改电池信息
                    if (PortableEnergyBatteryService.self().lease(deviceOrder.getPortableBatterySn(), deviceOrder.getTradeNo(), deviceOrder.getCreateDate())) {
                        //触发事件监听
                        businessEventListener.leaseFinish(deviceOrder,deviceOrder.getPortableBatterySn(),BXSCNShopOrderEnum.State.Lease.index());
                        JdbcSession.commit();
                        logState = ELogState.Success.index();
                        errorMsg = null;
                    } else {
                        errorMsg = "修改电池租借信息失败";
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
                errorMsg = e.getMessage();
            } finally {
                JdbcSession.end();
            }

            if (ELogState.Success.index().equals(logState)) {
                BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
                return true;
            } else {
                BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
                throw new LogicException(errorMsg);
            }
        }
        return false;
    }

    /**
     * 计算租金
     * @param deviceOrder
     * @param memberCouponService
     * @return
     */
    public PayInfo calculatePrice(BXSCNShopOrder deviceOrder,IMemberCouponService memberCouponService){
        PayInfo payInfo = new PayInfo();
        
        Long hour = DateTools.differenceHour(deviceOrder.getStartDate(),payInfo.finishDate);
        if(hour > 0) {
        	payInfo.useDay = hour.intValue() / 24;
        	long temp = hour % 24;
        	if(temp > 8) {
        		payInfo.useDay = payInfo.useDay + 1;
        	}
        }
        
        if(payInfo.useDay == 0){
            payInfo.useDay = 1;     //当天租借当天归还
        }

        Integer timeoutDay = 0;                         //预期外的天数
        if(payInfo.useDay > deviceOrder.getLeaseDay()){
            //如果超过预期，则预期内按阶梯价格，超出的按默认价格
            timeoutDay = payInfo.useDay - deviceOrder.getLeaseDay();
        }

        payInfo.payMoney =  deviceOrder.getDayMoney() * deviceOrder.getLeaseDay();      //预期租借天数，提前归还也支付这么多
        if(timeoutDay > 0){
            payInfo.payMoney =  payInfo.payMoney + (timeoutDay * deviceOrder.getTimeoutDayMoney());     //超时租借
        }
        payInfo.payMoneyLi = NumberTools.changeMoneyLi(NumberTools.changeMoney(payInfo.payMoney));

        //优惠券使用
        if(memberCouponService != null) {
            payInfo.memberCoupon = memberCouponService.getMemberCoupon(BXSCNConstants.BusinessTypeShop, deviceOrder);
            if (payInfo.memberCoupon != null) {
                deviceOrder.setCouponId(payInfo.memberCoupon.getId());
                deviceOrder.setCouponTitle(payInfo.memberCoupon.getTitle());
                Long discountMoney = 0L;
                if (ECouponType.DISCOUNT_COUPON.index().equals(payInfo.memberCoupon.getCouponType())) {
                    discountMoney = payInfo.payMoneyLi - NumberTools.discount(payInfo.payMoneyLi, payInfo.memberCoupon.getCouponDiscount());
                } else if (ECouponType.VOUCHERS.index().equals(payInfo.memberCoupon.getCouponType())) {
                    discountMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(payInfo.memberCoupon.getCouponMoney()));
                } else if (ECouponType.COUPON_DAY.index().equals(payInfo.memberCoupon.getCouponType())) {
                    Integer tempMoney = payInfo.memberCoupon.getCouponDay() * deviceOrder.getDayMoney();
                    discountMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(tempMoney));
                }
                deviceOrder.setDiscountMoney(discountMoney);
            }

            //计算优惠券
            if (deviceOrder.getDiscountMoney() != null && deviceOrder.getDiscountMoney() > 0) {
                payInfo.payMoneyLi = payInfo.payMoneyLi - deviceOrder.getDiscountMoney();
                if (payInfo.payMoneyLi < 0) {
                    payInfo.payMoneyLi = 0L;
                    payInfo.payMoney = 0;
                } else {
                    payInfo.payMoney = NumberTools.changeMoney(NumberTools.changeMoneyLi(payInfo.payMoneyLi));
                }
            }
        }

        //收取物流费用，不走优惠
        if(deviceOrder.getLogisticsMoney() > 0){
            payInfo.payMoney = payInfo.payMoney + deviceOrder.getLogisticsMoney();
            payInfo.payMoneyLi = NumberTools.changeMoneyLi(NumberTools.changeMoney(payInfo.payMoney));
        }
        //收取损坏费用，不走优惠
        if(deviceOrder.getDamageMoney() > 0){
            payInfo.payMoney = payInfo.payMoney + deviceOrder.getDamageMoney();
            payInfo.payMoneyLi = NumberTools.changeMoneyLi(NumberTools.changeMoney(payInfo.payMoney));
        }

        //这里使用支付金额做减法
        Integer walletMoney = NumberTools.changeMoney(NumberTools.changeMoneyLi(deviceOrder.getWalletMoney()));
        Integer money = deviceOrder.getPayMoney() + walletMoney;

        if(payInfo.payMoney > money){
            payInfo.payMoney = money;
            payInfo.payMoneyLi = NumberTools.changeMoneyLi(NumberTools.changeMoney(payInfo.payMoney));
        }else{
            //TODO 未来这里要计算支付与钱包组合支付退款

            payInfo.refundMoney = money - payInfo.payMoney;
            if(payInfo.refundMoney > 0){
                payInfo.refundMoneyLi = NumberTools.changeMoneyLi(NumberTools.changeMoney(payInfo.refundMoney));
            }else{
                payInfo.refundMoney = 0;
            }
        }

        if(BXSCNShopOrderEnum.State.LeaseClose.index().equals(deviceOrder.getState())){
            payInfo.state = BXSCNShopOrderEnum.State.RevertClose.index();
        }
        return payInfo;
    }

    /**
     * 预约到店归还完成，使用第三方支付
     * @param deviceOrder
     * @param payServiceFactory
     * @param memberCouponService
     * @param operateInfo
     * @return -1:处理失败，1:订单退款中，2:订单已完结，需要同步会员订单
     * @throws LogicException
     */
    public int revertFinish(BXSCNShopOrder deviceOrder,IPayServiceFactory payServiceFactory, IMemberCouponService memberCouponService
            , OperateInfo operateInfo) throws LogicException {
        if(deviceOrder != null && StringTools.isNotBlank(deviceOrder.getTradeNo())) {
            if(BXSCNShopOrderEnum.State.Lease.index().equals(deviceOrder.getState()) || BXSCNShopOrderEnum.State.WaitRevert.index().equals(deviceOrder.getState())
                || BXSCNShopOrderEnum.State.LeaseClose.index().equals(deviceOrder.getState())){

                IMemberWalletService memberWalletService = payServiceFactory.getMemberWalletService();
                PayInfo payInfo = this.calculatePrice(deviceOrder,memberCouponService);

                //如果使用会员
                if(EPayType.EWallet.index().equals(deviceOrder.getPayType())){
                    return revertFinish(deviceOrder,payInfo,memberWalletService,memberCouponService,operateInfo);
                }


                Conditions conditions = new Conditions(BXSCNShopOrder.class);
                conditions.and().is("tradeNo",deviceOrder.getTradeNo());
                conditions.and().is("state",deviceOrder.getState());

                BXSCNShopOrder updateEntity = new BXSCNShopOrder();
                updateEntity.setRevertType(deviceOrder.getRevertType());
                updateEntity.setRevertPlaceId(deviceOrder.getRevertPlaceId());
                updateEntity.setRevertPlaceName(deviceOrder.getRevertPlaceName());
                updateEntity.setRevertProvince(deviceOrder.getRevertProvince());
                updateEntity.setRevertCity(deviceOrder.getRevertCity());
                updateEntity.setRevertCityArea(deviceOrder.getRevertCityArea());
                updateEntity.setRevertAreaCode(deviceOrder.getRevertAreaCode());
                updateEntity.setRevertAddress(deviceOrder.getRevertAddress());
                updateEntity.setRevertLatitude(deviceOrder.getRevertLatitude());
                updateEntity.setRevertLongitude(deviceOrder.getRevertLongitude());
                updateEntity.setRevertAgentId(deviceOrder.getRevertAgentId());
                updateEntity.setRevertOperatorId(operateInfo.getOperatorId());
                updateEntity.setRevertOperator(operateInfo.getOperator());

                updateEntity.setState(payInfo.state);
                updateEntity.setCouponId(deviceOrder.getCouponId());
                updateEntity.setCouponTitle(deviceOrder.getCouponTitle());
                updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
                updateEntity.setEndDate(payInfo.finishDate);
                updateEntity.setUseDay(payInfo.useDay);
                updateEntity.setMoney(payInfo.payMoneyLi);      //修改订单总金额
                updateEntity.setPayMoney(payInfo.payMoney);
                updateEntity.setFinishDate(payInfo.finishDate);
                if(payInfo.refundMoney > 0) {
                    updateEntity.setPayState(BXSCNShopOrderEnum.PayState.DepositRefund.index());
                }else{
                    updateEntity.setPayState(BXSCNShopOrderEnum.PayState.PaySuccess.index());
                }

                boolean isSuccess = false;
                JdbcSession.begin();
                try {
                    if(dao.updateNotNull(updateEntity, conditions) > 0){
                        operateInfo.setOperateNote(deviceOrder.getTradeNo() + "订单完成操作钱包");
                        //退还押金并支付租借
                        if (memberWalletService.reduceFreezeMoney(deviceOrder.getMemberId(), deviceOrder.getIncomeMoney(), operateInfo)) {
                            if(PortableEnergyBatteryService.self().revert(deviceOrder.getPortableBatterySn())) {
                                boolean flag = true;
                                if(payInfo.memberCoupon != null) {
                                    if(!memberCouponService.toUsed(payInfo.memberCoupon.getId(),deviceOrder.getTradeNo(),deviceOrder.getCreateDate())){
                                        log.error("{{0}}订单修改会员优惠券{{1}}状态失败", deviceOrder.getTradeNo(),payInfo.memberCoupon.getId());
                                        flag = false;
                                    }
                                }
                                if(flag) {
                                    JdbcSession.commit();
                                    isSuccess = true;
                                }
                            }else{
                                log.error("{{0}}订单修改{{1}}电池归还状态失败",deviceOrder.getTradeNo(),deviceOrder.getPortableBatterySn());
                            }
                        }else{
                            log.error("{{0}}订单修改{{1}}用户钱包失败",deviceOrder.getTradeNo(),deviceOrder.getMemberId());
                        }
                    }
                }catch (SQLException e){
                    log.error(e.getMessage(),e);
                }finally {
                    JdbcSession.end();
                }

                if(isSuccess){
                    Integer operateState = ELogState.Success.index();
                    String errorMsg = null;

                    //记录日志
                    operateInfo.setOperateNote("电池归还，完成订单，支付金额：" + NumberTools.changeMoney(payInfo.payMoney) + "元");
                    BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, operateState, errorMsg);

                    if(payInfo.refundMoney > 0) {
                        //触发押金退款
                        if (EPayType.WXPay.index().equals(deviceOrder.getPayType())) {
                            WXPayOrder payOrder = WXPayOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getPayTradeNo());
                            if (payOrder != null) {
                                WXPayNormalPayService payService = payServiceFactory.getWXPayNormalPayService(payOrder.getAppId(), BXSCNConstants.BusinessTypeShop);
                                if (payService != null) {
                                    if (noOperateTo(deviceOrder.getTradeNo(), EOrderOperateState.Finishing.index())) {
                                        //触发退款
                                        try {
                                            String operateNote = deviceOrder.getTradeNo() + "订单电池归还后退款";
                                            WXRefundOrder refundOrder = WXRefundOrderService.self(deviceOrder.getCreateDate()).createRefundOrder(payOrder, payInfo.refundMoney, operateNote);
                                            if (refundOrder != null) {
                                                WXPayNormalRefundResponse externalResult = payService.applyRefundOrder(refundOrder);
                                                if (externalResult != null) {
                                                    if (StringTools.isNotBlank(externalResult.getCode()) && StringTools.isNotBlank(externalResult.getMessage())) {
                                                        operateState = ELogState.Fail.index();
                                                        errorMsg = externalResult.getMessage();
                                                    } else if (EWXPayNormalRefundState.SUCCESS.name().equals(externalResult.getStatus())) {
                                                        log.info("{{0}}订单微信直接退款成功，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                                                    } else if (EWXPayNormalRefundState.CLOSED.name().equals(externalResult.getStatus()) ||
                                                            EWXPayNormalRefundState.ABNORMAL.name().equals(externalResult.getStatus())) {
                                                        operateState = ELogState.Fail.index();
                                                        errorMsg = "退款订单已关闭或异常";
                                                        log.error("{{0}}订单微信退款失败，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                                                    }
                                                } else {
                                                    operateState = ELogState.Fail.index();
                                                    errorMsg = "微信退款失败，无响应";
                                                    log.error("{{0}}订单微信退款失败，无返回信息", payOrder.getTradeNo());
                                                }
                                            } else {
                                                operateState = ELogState.Fail.index();
                                                errorMsg = "创建微信退款订单失败";
                                            }
                                        } catch (Exception e) {
                                            log.error(e.getMessage(), e);
                                            operateState = ELogState.Fail.index();
                                            errorMsg = e.getMessage();
                                        }

                                        if (ELogState.Fail.index().equals(operateState)) {
                                            //失败回滚数据库
                                            faceOperateState(deviceOrder.getTradeNo(), EOrderOperateState.NoOperation.index());
                                        }
                                    } else {
                                        operateState = ELogState.Fail.index();
                                        errorMsg = "退款时锁定订单失败";
                                    }
                                } else {
                                    operateState = ELogState.Fail.index();
                                    errorMsg = "退款时未找到应用支付服务";
                                    log.error("{{0}}订单归还成功后未找到应用支付服务", deviceOrder.getTradeNo());
                                }
                            } else {
                                operateState = ELogState.Fail.index();
                                errorMsg = "退款时未找到支付订单";
                                log.error("{{0}}订单归还成功后未找到{{1}}支付订单", deviceOrder.getTradeNo(), deviceOrder.getPayTradeNo());
                            }
                        }
                        operateInfo.setOperateNote("第三方订单退款");
                        BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, operateState, errorMsg);
                        return 1;
                    }else {
                        return 2;
                    }
                }
            }else{
                log.error("{{0}}订单状态异常，无法归还，当前状态：{{1}}",deviceOrder.getTradeNo(),deviceOrder.getState());
            }
        }
        return -1;
    }

    /**
     * 预约到店归还完成，使用会员钱包
     * @param deviceOrder
     * @param memberWalletService
     * @param operateInfo
     * @return
     * @throws LogicException
     */
    private int revertFinish(BXSCNShopOrder deviceOrder, PayInfo payInfo,IMemberWalletService memberWalletService
            ,IMemberCouponService memberCouponService,OperateInfo operateInfo) throws LogicException {
        Conditions conditions = new Conditions(BXSCNShopOrder.class);
        conditions.and().is("tradeNo", deviceOrder.getTradeNo());
        conditions.and().is("state", deviceOrder.getState());

        BXSCNShopOrder updateEntity = new BXSCNShopOrder();
        updateEntity.setRevertType(deviceOrder.getRevertType());
        updateEntity.setRevertPlaceId(deviceOrder.getRevertPlaceId());
        updateEntity.setRevertPlaceName(deviceOrder.getRevertPlaceName());
        updateEntity.setRevertProvince(deviceOrder.getRevertProvince());
        updateEntity.setRevertCity(deviceOrder.getRevertCity());
        updateEntity.setRevertCityArea(deviceOrder.getRevertCityArea());
        updateEntity.setRevertAreaCode(deviceOrder.getRevertAreaCode());
        updateEntity.setRevertAddress(deviceOrder.getRevertAddress());
        updateEntity.setRevertLatitude(deviceOrder.getRevertLatitude());
        updateEntity.setRevertLongitude(deviceOrder.getRevertLongitude());
        updateEntity.setRevertOperatorId(operateInfo.getOperatorId());
        updateEntity.setRevertOperator(operateInfo.getOperator());
        updateEntity.setRevertAgentId(deviceOrder.getRevertAgentId());

        updateEntity.setState(payInfo.state);
        updateEntity.setCouponId(deviceOrder.getCouponId());
        updateEntity.setCouponTitle(deviceOrder.getCouponTitle());
        updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
        updateEntity.setEndDate(payInfo.finishDate);
        updateEntity.setUseDay(payInfo.useDay);
        updateEntity.setMoney(payInfo.payMoneyLi);      //修改订单总金额
        updateEntity.setPayMoney(payInfo.payMoney);
        updateEntity.setFinishDate(payInfo.finishDate);
        updateEntity.setPayState(BXSCNShopOrderEnum.PayState.PaySuccess.index());

        JdbcSession.begin();
        try {
            if (dao.updateNotNull(updateEntity, conditions) > 0) {
                operateInfo.setOperateNote(deviceOrder.getTradeNo() + "订单完成操作钱包");
                //退还押金并支付租借
                if (memberWalletService.unfreezeAndReduceMoney(deviceOrder.getMemberId(), payInfo.refundMoneyLi, payInfo.payMoneyLi, operateInfo)) {
                    if (PortableEnergyBatteryService.self().revert(deviceOrder.getPortableBatterySn())) {
                        boolean flag = true;
                        if(payInfo.memberCoupon != null) {
                            if(!memberCouponService.toUsed(payInfo.memberCoupon.getId(),deviceOrder.getTradeNo(),deviceOrder.getCreateDate())){
                                log.error("{{0}}订单修改会员优惠券{{1}}状态失败", deviceOrder.getTradeNo(),payInfo.memberCoupon.getId());
                                flag = false;
                            }
                        }

                        if(flag) {
                            JdbcSession.commit();
                            return 2;
                        }
                    } else {
                        log.error("{{0}}订单修改{{1}}电池归还状态失败", deviceOrder.getTradeNo(), deviceOrder.getPortableBatterySn());
                    }
                } else {
                    log.error("{{0}}订单修改{{1}}用户钱包失败", deviceOrder.getTradeNo(), deviceOrder.getMemberId());
                }
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        } finally {
            JdbcSession.end();
        }
        return -1;
    }

    public boolean leaseToWaitRevert(String tradeNo){
        if(StringTools.isNotBlank(tradeNo)){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",tradeNo);
            conditions.and().is("state",BXSCNShopOrderEnum.State.Lease.index());
            conditions.and().is("payState",BXSCNShopOrderEnum.PayState.DepositSuccess.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setState(BXSCNShopOrderEnum.State.WaitRevert.index());

            try {
                return dao.updateNotNull(updateEntity,conditions) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean updateAgentIdByPlaceId(Long placeId,Long agentId){
        if(placeId != null){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("leasePlaceId",placeId);

            Map<String,Object> map = new HashMap<>();
            map.put("leaseAgentId",agentId);

            try {
                return dao.update(map,conditions) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean updateRevertAgentIdByPlaceId(Long placeId,Long agentId){
        if(placeId != null){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("revertPlaceId",placeId);

            Map<String,Object> map = new HashMap<>();
            map.put("revertAgentId",agentId);

            try {
                return dao.update(map,conditions) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public void lose(BXSCNShopOrder deviceOrder,IMemberWalletService memberWalletService,IMemberCouponService memberCouponService,OperateInfo operateInfo){
        if(BXSCNShopOrderEnum.State.WaitRevert.index().equals(deviceOrder.getState())) {
            //计算租金
            PayInfo payInfo = calculatePrice(deviceOrder, memberCouponService);
            if (payInfo != null) {
                if(payInfo.payMoney >= deviceOrder.getMoney()){
                    //超过押金
                    Conditions conditions = new Conditions(BXSCNShopOrder.class);
                    conditions.and().is("tradeNo", deviceOrder.getTradeNo());
                    conditions.and().is("state", BXSCNShopOrderEnum.State.WaitRevert.index());

                    BXSCNShopOrder updateEntity = new BXSCNShopOrder();
                    updateEntity.setRevertType(BXSCNShopOrderEnum.RevertType.Unknown.index());
                    updateEntity.setRevertOperatorId(operateInfo.getOperatorId());
                    updateEntity.setRevertOperator(operateInfo.getOperator());

                    updateEntity.setState(BXSCNShopOrderEnum.State.LeaseClose.index());
                    updateEntity.setCouponId(deviceOrder.getCouponId());
                    updateEntity.setCouponTitle(deviceOrder.getCouponTitle());
                    updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
                    updateEntity.setEndDate(payInfo.finishDate);
                    updateEntity.setUseDay(payInfo.useDay);
                    updateEntity.setMoney(payInfo.payMoneyLi);      //修改订单总金额
                    updateEntity.setPayMoney(payInfo.payMoney);
                    updateEntity.setFinishDate(payInfo.finishDate);
                    updateEntity.setPayState(BXSCNShopOrderEnum.PayState.PaySuccess.index());

                    JdbcSession.begin();
                    try {
                        if (dao.updateNotNull(updateEntity, conditions) > 0) {
                            operateInfo.setOperateNote(deviceOrder.getTradeNo() + "订单完成操作钱包");
                            //扣除押金
                            if (memberWalletService.reduceFreezeMoney(deviceOrder.getMemberId(), payInfo.payMoneyLi, operateInfo)) {
                                if (PortableEnergyBatteryService.self().lose(deviceOrder.getPortableBatterySn())) {
                                    boolean flag = true;
                                    if(payInfo.memberCoupon != null) {
                                        if(!memberCouponService.toUsed(payInfo.memberCoupon.getId(),deviceOrder.getTradeNo(),deviceOrder.getCreateDate())){
                                            log.error("{{0}}订单修改会员优惠券{{1}}状态失败", deviceOrder.getTradeNo(),payInfo.memberCoupon.getId());
                                            flag = false;
                                        }
                                    }

                                    if(flag) {
                                        JdbcSession.commit();
                                    }
                                } else {
                                    log.error("{{0}}订单修改{{1}}电池归还状态失败", deviceOrder.getTradeNo(), deviceOrder.getPortableBatterySn());
                                }
                            } else {
                                log.error("{{0}}订单修改{{1}}用户钱包失败", deviceOrder.getTradeNo(), deviceOrder.getMemberId());
                            }
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(), e);
                    } catch (LogicException e) {
                        log.error(e.getMessage(), e);
                    } finally {
                        JdbcSession.end();
                    }
                }
            }
        }
    }

    /**
     * 延期租借时间
     * @param deviceOrder
     * @param startDate
     * @param operateInfo
     */
    public boolean extensionLeaseDay(BXSCNShopOrder deviceOrder,Date startDate,OperateInfo operateInfo) throws LogicException {
        if(BXSCNShopOrderEnum.State.LeaseTimeout.index().equals(deviceOrder.getState()) ||
                BXSCNShopOrderEnum.State.WaitLease.index().equals(deviceOrder.getState())){

            Date date = DateUtils.addDays(startDate,deviceOrder.getLeaseDay());
            if(date.before(new Date())){
                throw new LogicException("租借时间过期");
            }

            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",deviceOrder.getTradeNo());
            conditions.and().is("state",deviceOrder.getState());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setState(BXSCNShopOrderEnum.State.WaitLease.index());
            updateEntity.setStartDate(startDate);
            updateEntity.setEndDate(date);

            try{
                if(dao.updateNotNull(updateEntity,conditions) > 0){
                    //记录日志
                    BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, ELogState.Success.index(), null);
                    return true;
                }
            }catch (SQLException e){
                e.getMessage();
            }
        }else{
            throw new LogicException("当前订单状态无法延期");
        }
        return false;
    }

    /**
     * 完成订单
     * @param deviceOrder
     * @param payMoney
     * @param payServiceFactory
     * @param operateInfo
     * @return -1:处理失败，1:订单退款中，2:订单已完结，需要同步会员订单
     * @throws LogicException
     */
    public int finish(BXSCNShopOrder deviceOrder, Integer payMoney, IPayServiceFactory payServiceFactory, OperateInfo operateInfo) throws LogicException {
        int result = -1;
        if (BXSCNShopOrderEnum.State.WaitLease.index().equals(deviceOrder.getState()) || BXSCNShopOrderEnum.State.Lease.index().equals(deviceOrder.getState()) 
        		|| BXSCNShopOrderEnum.State.WaitRevert.index().equals(deviceOrder.getState()) 
        		|| BXSCNShopOrderEnum.State.LeaseTimeout.index().equals(deviceOrder.getState())) {
            if (EPayType.WXPay.index().equals(deviceOrder.getPayType())) {
                WXPayOrder payOrder = WXPayOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getPayTradeNo());
                if (payOrder == null) {
                    throw new LogicException("未找到本地微信支付订单");
                }
                WXPayNormalPayService payService = payServiceFactory.getWXPayNormalPayService(payOrder.getAppId(), BXSCNConstants.BusinessType);
                if (payService == null) {
                    throw new LogicException("未配置应用支付服务");
                }
                result = finish(deviceOrder, payOrder, payMoney, payService, operateInfo);
            } else if (EPayType.EWallet.index().equals(deviceOrder.getPayType())) {

            }
        }else {
        	throw new LogicException(deviceOrder.getStateName() + "的订单无法完成");
        }
        
        if(result > 0) {
        	if(StringTools.isNotBlank(deviceOrder.getPortableBatterySn())){
        		if (!PortableEnergyBatteryService.self().revert(deviceOrder.getPortableBatterySn())) {
        			log.error("归还电池操作失败");
        		}
        	}
        	return result;
        }
        return -1;
    }

    private int finish(BXSCNShopOrder deviceOrder, WXPayOrder payOrder, Integer payMoney, WXPayNormalPayService payService, OperateInfo operateInfo) throws LogicException {
        if (EOrderOperateState.NoOperation.index().equals(deviceOrder.getOperateState())) {
            Integer refundMoney = 0;
            if (payOrder.getPayMoney() < payMoney) {
                throw new LogicException("客户支付金额小于结算金额，订单无法完成");
            } else if (payOrder.getPayMoney() > payMoney) {
                //单位转化，厘变分
                refundMoney = payOrder.getPayMoney() - payMoney;
            }

            Integer operateState = ELogState.Success.index();
            String errorMsg = null;

            Long money = NumberTools.changeMoneyLi(NumberTools.changeMoney(payMoney));

            //直接修改金额
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",deviceOrder.getTradeNo());
            conditions.and().is("operateState", deviceOrder.getOperateState());
            conditions.and().is("state",deviceOrder.getState());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
            updateEntity.setMoney(money);
            updateEntity.setPayMoney(payMoney);
            updateEntity.setFinishDate(new Date());
            if(refundMoney > 0) {
                updateEntity.setPayState(BXSCNShopOrderEnum.PayState.DepositRefund.index());
            }else{
                updateEntity.setPayState(BXSCNShopOrderEnum.PayState.PaySuccess.index());
            }

            try {
                if (dao.updateNotNull(updateEntity,conditions) <= 0) {
                    operateState = ELogState.Fail.index();
                    errorMsg = "修改数据库失败";
                }
            } catch (SQLException e) {
                operateState = ELogState.Fail.index();
                errorMsg = e.getMessage();
                log.error(e.getMessage(), e);
            }

            //记录日志
            BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, operateState, errorMsg);

            if (ELogState.Success.index().equals(operateState)) {
                if (refundMoney > 0) {
                    if(noOperateTo(deviceOrder.getTradeNo(),EOrderOperateState.Finishing.index())) {
                        //触发退款
                        WXRefundOrder refundOrder = WXRefundOrderService.self(deviceOrder.getCreateDate()).createRefundOrder(payOrder, refundMoney, operateInfo.getOperateNote());
                        WXPayNormalRefundResponse externalResult = payService.applyRefundOrder(refundOrder);
                        if (externalResult != null) {
                            if(StringTools.isNotBlank(externalResult.getCode()) && StringTools.isNotBlank(externalResult.getMessage())){
                                operateState = ELogState.Fail.index();
                                errorMsg = externalResult.getMessage();
                            }else if (EWXPayNormalRefundState.SUCCESS.name().equals(externalResult.getStatus())){
                                log.info("{{0}}订单微信直接退款成功，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                            }else if(EWXPayNormalRefundState.CLOSED.name().equals(externalResult.getStatus()) ||
                                    EWXPayNormalRefundState.ABNORMAL.name().equals(externalResult.getStatus())) {
                                operateState = ELogState.Fail.index();
                                errorMsg = "退款订单已关闭或异常";
                                log.error("{{0}}订单微信退款失败，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                            }
                        } else {
                            operateState = ELogState.Fail.index();
                            errorMsg = "微信退款失败，无响应";
                            log.error("{{0}}订单微信退款失败，无返回信息", payOrder.getTradeNo());
                        }

                        if (ELogState.Fail.index().equals(operateState)) {
                            //失败回滚数据库
                            faceOperateState(deviceOrder.getTradeNo(),EOrderOperateState.NoOperation.index());
                        }
                    }else{
                        operateState = ELogState.Fail.index();
                        errorMsg = "完成时锁定订单失败";
                    }

                    //记录日志
                    operateInfo.setOperateNote("第三方订单退款");
                    BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, operateState, errorMsg);
                }
            }

            if (ELogState.Success.index().equals(operateState)) {
                if (refundMoney > 0) {
                    return 1;
                }else{
                    return 2;
                }
            }
        }
        return -1;
    }

    public int cancel(BXSCNShopOrder deviceOrder, IPayServiceFactory payServiceFactory, OperateInfo operateInfo) throws LogicException {
        if (BXSCNShopOrderEnum.PayState.Cancel.index().equals(deviceOrder.getPayState())) {
            throw new LogicException("设备订单已撤销");
        }

        int result = -1;
        if (BXSCNShopOrderEnum.PayState.PaySuccess.index().equals(deviceOrder.getPayState())
                || BXSCNShopOrderEnum.PayState.DepositSuccess.index().equals(deviceOrder.getPayState())) {
            if (EPayType.WXPay.index().equals(deviceOrder.getPayType())) {
                WXPayOrder payOrder = WXPayOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getPayTradeNo());
                if (payOrder == null) {
                    throw new LogicException("未找到本地微信支付订单");
                }
                WXPayNormalPayService payService = payServiceFactory.getWXPayNormalPayService(payOrder.getAppId(), BXSCNConstants.BusinessTypeShop);
                if (payService == null) {
                    throw new LogicException("未配置应用支付服务");
                }
                result = cancel(deviceOrder, payOrder, payService, operateInfo);
                if(result > 0){
                    if(BXSCNShopOrderEnum.PayState.DepositSuccess.index().equals(deviceOrder.getPayState())){
                        //操作会员钱包
                        operateInfo.setOperateNote(deviceOrder.getTradeNo() + "订单撤销退款");
                        if(!payServiceFactory.getMemberWalletService().reduceFreezeMoney(deviceOrder.getMemberId(),deviceOrder.getIncomeMoney(),operateInfo)){
                            log.error("{{0}}订单撤销退款减少{{1}}会员冻结金额：{{2}}失败",deviceOrder.getTradeNo(),deviceOrder.getMemberId(),deviceOrder.getIncomeMoney());
                        }
                    }
                }
            } else if (EPayType.EWallet.index().equals(deviceOrder.getPayType())) {
            	result = cancel(deviceOrder, payServiceFactory.getMemberWalletService(), operateInfo);
            }
        }else{
            throw new LogicException("设备订单状态为："+deviceOrder.getPayStateName()+"，无法查询");
        }
        
        if(result > 0) {
        	if(StringTools.isNotBlank(deviceOrder.getPortableBatterySn())){
        		if (!PortableEnergyBatteryService.self().revert(deviceOrder.getPortableBatterySn())) {
        			log.error("归还电池操作失败");
        		}
        	}
        }
        return result;
    }

    private int cancel(BXSCNShopOrder deviceOrder, WXPayOrder payOrder,WXPayNormalPayService payService, OperateInfo operateInfo) throws LogicException {
        if(EOrderOperateState.NoOperation.index().equals(deviceOrder.getOperateState())) {
            Integer refundMoney = deviceOrder.getPayMoney();
            Integer logState = ELogState.Success.index();
            String errorMsg = null;

            if (refundMoney > 0) {
                if(noOperateTo(deviceOrder.getTradeNo(),EOrderOperateState.Cancelling.index())) {
                    //触发退款
                    try {
                        WXRefundOrder refundOrder = WXRefundOrderService.self(deviceOrder.getCreateDate()).createRefundOrder(payOrder, refundMoney, operateInfo.getOperateNote());
                        if (refundOrder != null) {
                            WXPayNormalRefundResponse externalResult = payService.applyRefundOrder(refundOrder);
                            if (externalResult != null) {
                                if(StringTools.isNotBlank(externalResult.getCode()) && StringTools.isNotBlank(externalResult.getMessage())){
                                    logState = ELogState.Fail.index();
                                    errorMsg = externalResult.getMessage();
                                }else if (EWXPayNormalRefundState.SUCCESS.name().equals(externalResult.getStatus())){
                                    log.info("{{0}}订单微信直接退款成功，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                                }else if(EWXPayNormalRefundState.CLOSED.name().equals(externalResult.getStatus()) ||
                                        EWXPayNormalRefundState.ABNORMAL.name().equals(externalResult.getStatus())) {
                                    logState = ELogState.Fail.index();
                                    errorMsg = "退款订单已关闭或异常";
                                    log.error("{{0}}订单微信退款失败，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                                }
                            } else {
                                logState = ELogState.Fail.index();
                                errorMsg = "微信退款失败，无响应";
                                log.error("{{0}}订单微信退款失败，无返回信息", payOrder.getTradeNo());
                            }
                        } else {
                            logState = ELogState.Fail.index();
                            errorMsg = "创建微信退款订单失败";
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                        logState = ELogState.Fail.index();
                        errorMsg = e.getMessage();
                    }finally {
                        if (ELogState.Fail.index().equals(logState)) {
                            //失败回滚数据库
                            faceOperateState(deviceOrder.getTradeNo(), EOrderOperateState.NoOperation.index());
                        }
                    }
                }else {
                    logState = ELogState.Fail.index();
                    errorMsg = "退款时锁定订单失败";
                }

                //记录日志
                operateInfo.setOperateNote("【撤销订单】" + operateInfo.getOperateNote());
                BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
                if (ELogState.Success.index().equals(logState)) {
                    return 1;
                }else{
                    throw new LogicException(errorMsg);
                }
            } else {
                Conditions conditions = new Conditions(BXSCNShopOrder.class);
                conditions.and().is("tradeNo", deviceOrder.getTradeNo());
                conditions.and().is("operateState", deviceOrder.getOperateState());
                conditions.and().is("state", deviceOrder.getState());

                BXSCNShopOrder updateEntity = new BXSCNShopOrder();
                updateEntity.setTradeNo(deviceOrder.getTradeNo());
                updateEntity.setMoney(0L);        //撤销时修改订单金额
                updateEntity.setPayMoney(0);
                updateEntity.setPayState(BXSCNShopOrderEnum.PayState.Cancel.index());
                //非终结状态，则修改为失败状态
                if (BXSCNShopOrderEnum.State.Lease.index().equals(deviceOrder.getState())) {
                    updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
                } else if (BXSCNShopOrderEnum.State.WaitLease.index().equals(deviceOrder.getState())) {
                    updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
                } else if (BXSCNShopOrderEnum.State.WaitRevert.index().equals(deviceOrder.getState())) {
                    updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
                }

                try {
                    if (dao.updateNotNull(updateEntity) <= 0) {
                        logState = ELogState.Fail.index();
                        errorMsg = "修改数据库失败";
                    }
                } catch (SQLException e) {
                    logState = ELogState.Fail.index();
                    errorMsg = e.getMessage();
                    log.error(e.getMessage(), e);
                }

                //记录日志
                operateInfo.setOperateNote("【撤销订单】" + operateInfo.getOperateNote());
                BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
                if (ELogState.Success.index().equals(logState)) {
                    return 2;
                }else{
                    throw new LogicException(errorMsg);
                }
            }
        }
        return -1;
    }

    private int cancel(BXSCNShopOrder deviceOrder,IMemberWalletService memberWalletService, OperateInfo operateInfo)throws LogicException {
        if(EOrderOperateState.NoOperation.index().equals(deviceOrder.getOperateState())) {
            Long refundMoney = deviceOrder.getWalletMoney();
            Integer logState = ELogState.Success.index();
            String errorMsg = null;

            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo", deviceOrder.getTradeNo());
            conditions.and().is("operateState", deviceOrder.getOperateState());
            conditions.and().is("state", deviceOrder.getState());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setTradeNo(deviceOrder.getTradeNo());
            updateEntity.setMoney(0L);          //撤销时修改订单金额
            updateEntity.setWalletMoney(0L);
            updateEntity.setPayState(BXSCNShopOrderEnum.PayState.Cancel.index());
            updateEntity.setCancelDate(new Date());

            //非终结状态，则修改为失败状态
            if (BXSCNShopOrderEnum.State.Lease.index().equals(deviceOrder.getState())) {
                updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
            } else if (BXSCNShopOrderEnum.State.WaitLease.index().equals(deviceOrder.getState())) {
                updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
            }

            JdbcSession.begin();
            try {
                if (dao.updateNotNull(updateEntity) > 0) {
                    if (refundMoney > 0) {
                        if(BXSCNShopOrderEnum.PayState.DepositSuccess.index().equals(deviceOrder.getPayState())) {
                            if (memberWalletService.reduceFreezeMoney(deviceOrder.getMemberId(), deviceOrder.getWalletMoney(), operateInfo)) {
                                JdbcSession.commit();
                            } else {
                                logState = ELogState.Fail.index();
                                errorMsg = "解冻会员金额失败";
                            }
                        }else if(BXSCNShopOrderEnum.PayState.PaySuccess.index().equals(deviceOrder.getPayState())){
                            if (memberWalletService.addMoney(deviceOrder.getMemberId(), refundMoney, operateInfo)) {
                                JdbcSession.commit();
                            } else {
                                logState = ELogState.Fail.index();
                                errorMsg = "新增会员钱包余额失败";
                            }
                        }else{
                            logState = ELogState.Fail.index();
                            errorMsg = "订单的支付状态错误，当前状态："+ deviceOrder.getPayStateName() + "无法撤销";
                        }
                    } else {
                        JdbcSession.commit();
                    }
                } else {
                    logState = ELogState.Fail.index();
                    errorMsg = "修改设备订单失败";
                }
            } catch (SQLException e) {
                logState = ELogState.Fail.index();
                errorMsg = e.getMessage();
                log.error(e.getMessage(), e);
            } finally {
                JdbcSession.end();
            }

            //记录日志
            BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
            if (ELogState.Success.index().equals(logState)) {
                return 2;
            }
        }
        return -1;
    }

    public int refund(BXSCNShopOrder deviceOrder, Integer refundMoney,IPayServiceFactory payServiceFactory, OperateInfo operateInfo)throws LogicException{
        if (!BXSCNShopOrderEnum.PayState.PaySuccess.index().equals(deviceOrder.getPayState())) {
            throw new LogicException("支付未成功");
        }

        if(EPayType.WXPay.index().equals(deviceOrder.getPayType())){
            WXPayOrder payOrder = WXPayOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getPayTradeNo());
            if (payOrder == null) {
                throw new LogicException("未找到本地微信支付订单");
            }
            WXPayNormalPayService normalPayService = payServiceFactory.getWXPayNormalPayService(payOrder.getAppId(), BXSCNConstants.BusinessTypeShop);
            if (normalPayService == null) {
                throw new LogicException("未找到微信支付服务");
            }
            return refund(deviceOrder,payOrder,refundMoney,normalPayService,operateInfo);
        }else if(EPayType.EWallet.index().equals(deviceOrder.getPayType())){

        }
        return -1;
    }

    private int refund(BXSCNShopOrder deviceOrder, WXPayOrder payOrder, Integer refundMoney, WXPayNormalPayService normalPayService
            , OperateInfo operateInfo) throws LogicException {
        if (deviceOrder.getPayMoney() < refundMoney) {
            throw new LogicException("没有足够的支付金额进行撤销");
        }
        Integer payMoney = deviceOrder.getPayMoney() - refundMoney;
        if (payMoney <= 0) {
            throw new LogicException("退款金额超界");
        }

        Integer logState = ELogState.Success.index();
        String errorMsg = null;

        if(noOperateTo(deviceOrder.getTradeNo(),EOrderOperateState.Refunding.index())){
            try {
                //触发退款
                WXRefundOrder refundOrder = WXRefundOrderService.self(deviceOrder.getCreateDate()).createRefundOrder(payOrder, refundMoney, operateInfo.getOperateNote());
                WXPayNormalRefundResponse externalResult = normalPayService.applyRefundOrder(refundOrder);
                if (externalResult != null) {
                    if(StringTools.isNotBlank(externalResult.getCode()) && StringTools.isNotBlank(externalResult.getMessage())){
                        logState = ELogState.Fail.index();
                        errorMsg = externalResult.getMessage();
                    }else if (EWXPayNormalRefundState.SUCCESS.name().equals(externalResult.getStatus())){
                        log.info("{{0}}订单微信直接退款成功，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                    }else if(EWXPayNormalRefundState.CLOSED.name().equals(externalResult.getStatus()) ||
                            EWXPayNormalRefundState.ABNORMAL.name().equals(externalResult.getStatus())) {
                        logState = ELogState.Fail.index();
                        errorMsg = "退款订单已关闭或异常";
                        log.error("{{0}}订单微信退款失败，返回信息：{{1}}", payOrder.getTradeNo(), JsonTools.toJson(externalResult));
                    }
                } else {
                    logState = ELogState.Fail.index();
                    errorMsg = "微信退款失败，无响应";
                    log.error("{{0}}订单微信退款失败，无返回信息", payOrder.getTradeNo());
                }
            } catch (Exception e) {
                logState = ELogState.Fail.index();
                errorMsg = e.getMessage();
                log.error(e.getMessage(), e);
            }finally {
                if (ELogState.Fail.index().equals(logState)) {
                    faceOperateState(deviceOrder.getTradeNo(), EOrderOperateState.NoOperation.index());
                }
            }
        }else{
            logState = ELogState.Fail.index();
            errorMsg = "退款时锁定订单失败";
        }

        //增加日志
        BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
        if(ELogState.Success.index().equals(logState)) {
            return 1;
        }
        return -1;
    }

    /**
     * 退款成功后调用
     * @param refundOrder
     * @param operateInfo
     * @return -1:处理失败，1:订单已撤销，2:部分退款完成 3:订单已完成
     */
    public int refundSuccess(WXRefundOrder refundOrder,OperateInfo operateInfo){
        BXSCNShopOrder deviceOrder = getByTradeNo(refundOrder.getBusinessTradeNo());
        if(deviceOrder == null){
            log.error("退款成功，未找到便携式电池门店订单，退款订单信息：{{0:json}}",refundOrder);
        }
        if(EOrderOperateState.Cancelling.index().equals(deviceOrder.getOperateState())){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",refundOrder.getBusinessTradeNo());
            conditions.and().is("operateState",EOrderOperateState.Cancelling.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setOperateState(EOrderOperateState.NoOperation.index());
            updateEntity.setPayState(BXSCNShopOrderEnum.PayState.Cancel.index());
            updateEntity.setMoney(0L);        //撤销时修改订单金额
            updateEntity.setPayMoney(0);
            updateEntity.setCancelDate(new Date());
            //非终结状态，则修改为失败状态
            if (BXSCNShopOrderEnum.State.Lease.index().equals(deviceOrder.getState())) {
                updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
            } else if (BXSCNShopOrderEnum.State.WaitLease.index().equals(deviceOrder.getState())) {
                updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
            } else if (BXSCNShopOrderEnum.State.WaitRevert.index().equals(deviceOrder.getState())) {
                updateEntity.setState(BXSCNShopOrderEnum.State.Close.index());
            }

            Integer logState = ELogState.Fail.index();
            String errorMsg = "修改订单状态失败";
            try {
                if(dao.updateNotNull(updateEntity,conditions) > 0){
                    logState = ELogState.Success.index();
                    errorMsg = null;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
                errorMsg = e.getMessage();
            }

            BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
            if(ELogState.Success.index().equals(logState)){
                return 1;
            }
        }else if(EOrderOperateState.Finishing.index().equals(deviceOrder.getOperateState())){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",refundOrder.getBusinessTradeNo());
            conditions.and().is("operateState",EOrderOperateState.Finishing.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setOperateState(EOrderOperateState.NoOperation.index());
            updateEntity.setPayState(BXSCNShopOrderEnum.PayState.PaySuccess.index());

            Integer logState = ELogState.Fail.index();
            String errorMsg = "修改订单状态失败";
            try {
                if(dao.updateNotNull(updateEntity,conditions) > 0){
                    logState = ELogState.Success.index();
                    errorMsg = null;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }

            BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
            if(ELogState.Success.index().equals(logState)){
                return 3;
            }
        }else if(EOrderOperateState.Refunding.index().equals(deviceOrder.getOperateState())){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",refundOrder.getBusinessTradeNo());
            conditions.and().is("operateState",EOrderOperateState.Refunding.index());

            //计算退款金额
            Long money = deviceOrder.getMoney();
            Integer payMoney = deviceOrder.getPayMoney();

            if(refundOrder.getRefundMoney() > 0) {
                payMoney = payMoney - refundOrder.getRefundMoney();
                if (payMoney > 0) {
                    money = money - NumberTools.changeMoneyLi(NumberTools.changeMoney(payMoney));
                } else {
                    //全部退款
                    payMoney = 0;
                    money = 0L;
                }
            }

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setMoney(money);
            updateEntity.setPayMoney(payMoney);
            updateEntity.setOperateState(EOrderOperateState.NoOperation.index());

            Integer logState = ELogState.Fail.index();
            String errorMsg = "修改订单状态失败";
            try {
                if(dao.updateNotNull(updateEntity,conditions) > 0){
                    logState = ELogState.Success.index();
                    errorMsg = null;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }

            BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, logState, errorMsg);
            if(ELogState.Success.index().equals(logState)){
                return 2;
            }
        }
        return -1;
    }

    public boolean refundFail(WXRefundOrder refundOrder,OperateInfo operateInfo){
        BXSCNShopOrder deviceOrder = getByTradeNo(refundOrder.getBusinessTradeNo());
        if(deviceOrder == null){
            log.error("退款成功，未找到设备订单，退款订单信息：{{0:json}}",refundOrder);
        }

        if(EOrderOperateState.Cancelling.index().equals(deviceOrder.getOperateState())){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",refundOrder.getBusinessTradeNo());
            conditions.and().is("operateState",EOrderOperateState.Cancelling.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setOperateState(EOrderOperateState.NoOperation.index());
            try {
                if(dao.updateNotNull(updateEntity,conditions) > 0){
                    return true;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }else if(EOrderOperateState.Refunding.index().equals(deviceOrder.getOperateState())) {
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo", refundOrder.getBusinessTradeNo());
            conditions.and().is("operateState", EOrderOperateState.Refunding.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setOperateState(EOrderOperateState.NoOperation.index());
            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                    return true;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }else if(EOrderOperateState.Finishing.index().equals(deviceOrder.getOperateState())) {
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo", refundOrder.getBusinessTradeNo());
            conditions.and().is("operateState", EOrderOperateState.Finishing.index());

            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
            updateEntity.setOperateState(EOrderOperateState.NoOperation.index());

            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                    return true;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public int synExternal(BXSCNShopOrder deviceOrder, IPayServiceFactory payServiceFactory, OperateInfo operateInfo)throws LogicException{
        if(BXSCNShopOrderEnum.PayState.DepositSuccess.index().equals(deviceOrder.getPayState())
                || BXSCNShopOrderEnum.PayState.DepositRefund.index().equals(deviceOrder.getPayState()) ){
            if(EPayType.WXPay.index().equals(deviceOrder.getPayType())){
                //检查退款订单，如果存在退款，则修改订单为完成，并修改订单支付金额
                List<WXRefundOrder> refundOrderList = WXRefundOrderService.self(deviceOrder.getCreateDate()).findByBusinessTradeNo(deviceOrder.getTradeNo());
                if(refundOrderList != null && refundOrderList.size() > 0){
                    boolean flag = false;
                    Integer payMoney = 0;
                    Integer refundMoney = 0;
                    for(WXRefundOrder wxRefundOrder : refundOrderList){
                        if(ERefundState.Wait.index().equals(wxRefundOrder.getRefundStatus())){
                            WXPayNormalPayService payService = payServiceFactory.getWXPayNormalPayService(wxRefundOrder.getAppId(),BXSCNConstants.BusinessTypeShop);
                            if(payService == null){
                                throw new LogicException("未找到微信普通支付服务");
                            }
                            //如果是等待中，检查是否退款成功
                            WXPayNormalRefundResponse refundResponse = payService.applyRefundOrder(wxRefundOrder);
                            if(refundResponse != null){
                            	log.info("查询第三方退款订单信息：{{0:json}}",refundResponse);
                            	payMoney = refundResponse.getAmount().getTotal();		//获取支付订单金额
                                if(EWXPayNormalRefundState.SUCCESS.name().equals(refundResponse.getStatus())){
                                    if(WXRefundOrderService.self(wxRefundOrder.getCreateDate()).toSuccess(wxRefundOrder.getTradeNo(),
                                            refundResponse.getTransaction_id(),JsonTools.toJson(refundResponse))){
                                        flag = true;
                                        refundMoney = refundMoney + refundResponse.getAmount().getRefund();
                                    }
                                }else if(EWXPayNormalRefundState.CLOSED.name().equals(refundResponse.getStatus())
                                        || EWXPayNormalRefundState.ABNORMAL.name().equals(refundResponse.getStatus())){
                                    String errorMsg = "退款订单已关闭";
                                    if(EWXPayNormalRefundState.ABNORMAL.name().equals(refundResponse.getStatus())){
                                        errorMsg = "退款订单异常";
                                    }
                                    if(WXRefundOrderService.self(wxRefundOrder.getCreateDate()).toFail(wxRefundOrder.getTradeNo(),
                                            errorMsg,JsonTools.toJson(refundResponse))){
                                        flag = true;
                                    }
                                }else{
                                    flag = false;       //无法完成
                                }
                            }else{
                                log.error("查询{{0}}退款订单失败，无响应",wxRefundOrder.getTradeNo());
                                flag = false;       //无法完成
                            }
                        }else if(ERefundState.Success.index().equals(wxRefundOrder.getRefundStatus())){
                            flag = true;
                            refundMoney = refundMoney + wxRefundOrder.getRefundMoney();
                            payMoney = wxRefundOrder.getPayMoney();		//同一个支付订单的退款订单其支付金额是一样的
                        }
                    }

                    if(flag){
                        Integer operateState = ELogState.Success.index();
                        Date finishDate = new Date();
                        //完成订单，检查退款是否小于订单订单
                        //因为业务订单完成后修改支付金额，根据第三方返回当前的押金
                        payMoney = payMoney - refundMoney;
                        if(payMoney > 0){
                            Conditions conditions = new Conditions(BXSCNShopOrder.class);
                            conditions.and().is("tradeNo", deviceOrder.getTradeNo());
                            conditions.and().is("operateState", deviceOrder.getOperateState());
                            conditions.and().is("state", deviceOrder.getState());

                            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
                            updateEntity.setPayState(BXSCNShopOrderEnum.PayState.PaySuccess.index());
                            updateEntity.setPayMoney(payMoney);
                            updateEntity.setFinishDate(finishDate);

                            try {
                                if (dao.updateNotNull(updateEntity,conditions) <= 0) {
                                    operateState = ELogState.Fail.index();
                                }
                            } catch (SQLException e) {
                                operateState = ELogState.Fail.index();
                                log.error(e.getMessage(), e);
                            }
                            if(ELogState.Success.index().equals(operateState)) {
                                //记录日志
                                BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, operateState, null);

                                deviceOrder.setPayState(BXSCNShopOrderEnum.PayState.PaySuccess.index());
                                deviceOrder.setPayMoney(payMoney);
                                deviceOrder.setFinishDate(finishDate);
                                return 3;
                            }
                        }else if(payMoney == 0){
                            Conditions conditions = new Conditions(BXSCNShopOrder.class);
                            conditions.and().is("tradeNo", deviceOrder.getTradeNo());
                            conditions.and().is("operateState", deviceOrder.getOperateState());
                            conditions.and().is("state", deviceOrder.getState());

                            BXSCNShopOrder updateEntity = new BXSCNShopOrder();
                            updateEntity.setPayState(BXSCNShopOrderEnum.PayState.Cancel.index());
                            updateEntity.setCancelDate(new Date());

                            try {
                                if (dao.updateNotNull(updateEntity,conditions) <= 0) {
                                    operateState = ELogState.Fail.index();
                                }
                            } catch (SQLException e) {
                                operateState = ELogState.Fail.index();
                                log.error(e.getMessage(), e);
                            }
                            if(ELogState.Success.index().equals(operateState)) {
                                //记录日志
                                BXSCNShopOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, operateState, null);
                                return 1;
                            }
                        }else{
                            log.error("{{0}}便携式储能电池门店订单，退款金额大于支付金额",deviceOrder.getTradeNo());
                        }
                    }
                }else{
                    throw new LogicException("未找到退款订单");
                }
            }
        }
        return -1;
    }

    public boolean noOperateTo(String tradeNo,Integer operateState){
        if(StringTools.isNotBlank(tradeNo) && operateState != null){
            Conditions conditions = new Conditions(BXSCNShopOrder.class);
            conditions.and().is("tradeNo",tradeNo);
            conditions.and().is("operateState",EOrderOperateState.NoOperation.index());

            BXSCNShopOrder deviceOrder = new BXSCNShopOrder();
            deviceOrder.setOperateState(operateState);

            try {
                return dao.updateNotNull(deviceOrder,conditions) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean faceOperateState(String tradeNo,Integer operateState){
        if(StringTools.isNotBlank(tradeNo) && operateState != null){
            BXSCNShopOrder deviceOrder = new BXSCNShopOrder();
            deviceOrder.setTradeNo(tradeNo);
            deviceOrder.setOperateState(operateState);

            try {
                return dao.updateNotNull(deviceOrder) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean forceUpdatePortableBatterySn(String tradeNo,String portableBatterySn){
        if(StringTools.isNotBlank(tradeNo) && StringTools.isNotBlank(portableBatterySn)){
            BXSCNShopOrder deviceOrder = new BXSCNShopOrder();
            deviceOrder.setTradeNo(tradeNo);
            deviceOrder.setPortableBatterySn(portableBatterySn);

            try {
                return dao.updateNotNull(deviceOrder) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean forceUpdateMoney(String tradeNo,Long money,Integer payMoney){
        if(StringTools.isNotBlank(tradeNo) && (money != null || payMoney != null)){
            BXSCNShopOrder deviceOrder = new BXSCNShopOrder();
            deviceOrder.setTradeNo(tradeNo);
            deviceOrder.setMoney(money);
            deviceOrder.setPayMoney(payMoney);

            try {
                return dao.updateNotNull(deviceOrder) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public static class PayInfo {

        public Integer state = BXSCNShopOrderEnum.State.RevertFinish.index();
        public Integer useDay = 0;
        public Integer payMoney = 0;
        public Long payMoneyLi = 0L;
        public Integer refundMoney = 0;
        public Long refundMoneyLi = 0L;
        public Date finishDate = new Date();
        public IMemberCoupon memberCoupon = null;
    }
}
